﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.


using McMaster.NETCore.Plugins;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
using Serilog.Sinks.SystemConsole.Themes;
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using WeaveVerify;

namespace IdentityServer
{
    public class Program
    {
        static IConfigurationBuilder builder = new ConfigurationBuilder().SetBasePath(AppDomain.CurrentDomain.BaseDirectory).AddJsonFile("config.json");

        public static ConcurrentDictionary<String, IdentityBase> keyValuePairs = GetService();
        internal static ConcurrentDictionary<string, int> usreerror=new ConcurrentDictionary<string, int>();
        internal static ConcurrentDictionary<string, DateTime> usreerrortime=new ConcurrentDictionary<string, DateTime>();

        public static void Main(string[] args)
        {
            Console.Title = "IdentityServer4 - 认证中心";

            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
            var config = builder.Build();

            OAuthConfig.UserApi.ApiName = string.IsNullOrWhiteSpace(config["apiname"]) ? "api1" : config["apiname"];
            var certificate = new X509Certificate2("server.pfx", config["httpspassword"]);
            return WebHost.CreateDefaultBuilder().UseUrls(config["applicationUrl"])
                    .UseStartup<Startup>().UseKestrel(options =>
                    {
                        options.ConfigureHttpsDefaults(
                            
                            options => { 
                                options.ServerCertificate = certificate;
                              //  options.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13;
                            });
                    })
                    .UseSerilog((context, configuration) =>
                    {
                        configuration
                            .MinimumLevel.Debug()
                        //    .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
                        //    .MinimumLevel.Override("System", LogEventLevel.Warning)
                        //    .MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information)
                        //    .Enrich.FromLogContext()
                            .WriteTo.File(@"identityserver4_log.txt")
                            .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate);
                    });
        }
        public static ConcurrentDictionary<String, IdentityBase> GetService()
        {
            ConcurrentDictionary<String, IdentityBase> listservice = new ConcurrentDictionary<String, IdentityBase>();
            //插件目录搜索
            string[] plugins = Directory.GetDirectories(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins"));
            foreach (string plugin in plugins)
            {
                var mainDll = Directory.GetFiles(plugin, "*.deps.json").FirstOrDefault()?.Replace(".deps.json", ".dll");
                if (string.IsNullOrWhiteSpace(mainDll)) continue;
                try
                {
                    // 加载程序集
                    var p = PluginLoader.CreateFromAssemblyFile(mainDll
                        //内存加载，以便可以热更新，其实没必要
                        //此处改为false，否则会出现偶发性返回SqlSugar未找到的问题
                        , isUnloadable: false
                        //与宿主共享的类型，减少DLL地狱
                        , sharedTypes: new[] { typeof(IdentityBase) });
                    var pluginType = p.LoadDefaultAssembly().GetTypes().Where(d => typeof(IdentityBase).IsAssignableFrom(d));
                    //创建插件对象并调用
                    foreach (Type type in pluginType)
                    {
                        try
                        {
                            IdentityBase result = Activator.CreateInstance(type) as IdentityBase;
                            if (result == null) continue;
                            if(!listservice.TryAdd(result.PrjName, result))continue;
                            Console.WriteLine("GetService--已经加载-" + result.PrjName);
                        }
                        catch (Exception ee2)
                        {
                            // Console.WriteLine(tt.FullName + "GetService22---" + ee2.Message);
                        }
                    }
                    //卸载程序集
                    //context.Unload();
                }
                catch (Exception e)
                {
                    // Console.WriteLine(file+"---GetService---" +e.Message); 
                }
            }
            return listservice;
        }
    }
}